package com.mldong.flow.engine.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mldong.flow.engine.entity.ProcessDefine;
import com.mldong.flow.engine.enums.ProcessDefineStateEnum;
import com.mldong.flow.engine.mapper.ProcessDefineMapper;
import com.mldong.flow.engine.model.ProcessModel;
import com.mldong.flow.engine.parser.ModelParser;
import com.mldong.flow.engine.service.ProcessDefineService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 *
 * 流程定义服务实现类
 * @author mldong
 * @date 2023/5/30
 */
@Service
@AllArgsConstructor
public class ProcessDefineServiceImpl implements ProcessDefineService {
    private final ProcessDefineMapper processDefineMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long deploy(String json) {
        Date now = new Date();
        byte [] bytes = json.getBytes();
        // 1. json定义文件转成流程模型
        ProcessModel processModel = ModelParser.parse(bytes);
        // 2. 根据名称查询，取最新版本的流程定义记录
        List<ProcessDefine> processDefineList = processDefineMapper.selectList(
                Wrappers.lambdaQuery(ProcessDefine.class)
                        .eq(ProcessDefine::getName,processModel.getName())
                        .orderByDesc(ProcessDefine::getId)
        );
        ProcessDefine processDefine = null;
        // 3.1 如果存在，则版本+1，并插入一条新的流程定义记录
        if(!processDefineList.isEmpty()) {
            processDefine = processDefineList.get(0);
            processDefine.setId(null);
            processDefine.setVersion(processDefine.getVersion()+1);
        } else {
            // 3.2 如果不存在，则版本默认为1，并插入一条新的流程定义记录
            processDefine = new ProcessDefine();
            processDefine.setVersion(0);
        }
        processDefine.setName(processModel.getName());
        processDefine.setDisplayName(processModel.getDisplayName());
        processDefine.setType(processModel.getType());
        processDefine.setCreateTime(now);
        processDefine.setUpdateTime(now);
        processDefine.setState(ProcessDefineStateEnum.ENABLE.getCode());
        processDefine.setContent(bytes);
        processDefineMapper.insert(processDefine);
        return processDefine.getId();
    }
}
